<template>
  <div class="api-page">
    <skeleton v-if="loading" />
    <div v-else class="base-info">
      <h1 style="margin-bottom: 5px;">{{ detail.title }}</h1>
      <div v-if="isReload">
        <a-alert type="info" show-icon>
          <template #message>
            <span>{{ t("apiPage.update.tip") }}，</span>
            <a-button size="small" type="link" @click="onReload">{{
              t("apiPage.update.button")
            }}</a-button>
          </template>
        </a-alert>
      </div>
      <div class="text-list" style="margin-bottom: 10px">
        <div v-if="detail.author" class="text-list-item">
          <span class="text-label">{{ t("apiPage.author") }}：</span>
          <span class="text-value">{{ detail.author }}</span>
        </div>
        <div v-if="detail.tag && detail.tag.length" class="text-list-item">
          <span class="text-label">{{ t("apiPage.tag") }}：</span>
          <span class="text-value">
            <a-tag v-if="detail.tag && typeof detail.tag === 'string'">{{ detail.tag }}</a-tag>
            <a-tag v-else v-for="(item, index) in detail.tag" :key="index">{{ item }}</a-tag>
          </span>
        </div>
      </div>
      <div class="api-url-box">
        <div
          v-if="methodList && methodList.length > 0"
          :class="['api-method-select']"
          :title="currentMethod"
        >
          <a-select :value="currentMethod" style="width: 100%" @change="onMethodChange">
            <a-select-option v-for="item in methodList" :key="item" :value="item">{{
              item
            }}</a-select-option>
          </a-select>
        </div>
        <div v-else :class="['api-url-method', currentMethod]">
          {{ detail.method }}
        </div>
        <div :class="['api-url-input', { 'method-multiple': methodList.length > 0 }]">
          <input v-model="detail.url" />
        </div>
        <div class="api-url-copy" @click="send" style="right: 44px;padding:0px;">
          <a-button type="primary" style="height: 38px;" >send</a-button>
        </div>
        <div class="api-url-copy" @click="onCopyUrl">
          <CopyOutlined />
        </div>
      </div>
      <div class="api-content">
        <a-tabs v-model:activeKey="activeKey" default-active-key="table">
          <a-tab-pane key="table" >
            <template #tab>
                <svg focusable="false" class="" data-icon="book" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M832 64H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V96c0-17.7-14.3-32-32-32zm-260 72h96v209.9L621.5 312 572 347.4V136zm220 752H232V136h280v296.9c0 3.3 1 6.6 3 9.3a15.9 15.9 0 0022.3 3.7l83.8-59.9 81.4 59.4c2.7 2 6 3.1 9.4 3.1 8.8 0 16-7.2 16-16V136h64v752z"></path></svg>
                <span style="margin-top: -2px;float: right;margin-left: 5px;">{{t('apiPage.docs')}}</span>
            </template>
            <table-tab :detail="detail" />
          </a-tab-pane>
          <a-tab-pane key="json">
            <template #tab>
                <svg focusable="false" class="" data-icon="book" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M832 64H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V96c0-17.7-14.3-32-32-32zm-260 72h96v209.9L621.5 312 572 347.4V136zm220 752H232V136h280v296.9c0 3.3 1 6.6 3 9.3a15.9 15.9 0 0022.3 3.7l83.8-59.9 81.4 59.4c2.7 2 6 3.1 9.4 3.1 8.8 0 16-7.2 16-16V136h64v752z"></path></svg>
                <span style="margin-top: -2px;float: right;margin-left: 5px;">{{t('apiPage.json')}}</span>
            </template>
            <json-tab :detail="detail" />
          </a-tab-pane>
          <a-tab-pane key="debug">
            <template #tab>
                <svg focusable="false" class="" data-icon="bug" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M304 280h56c4.4 0 8-3.6 8-8 0-28.3 5.9-53.2 17.1-73.5 10.6-19.4 26-34.8 45.4-45.4C450.9 142 475.7 136 504 136h16c28.3 0 53.2 5.9 73.5 17.1 19.4 10.6 34.8 26 45.4 45.4C650 218.9 656 243.7 656 272c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8 0-40-8.8-76.7-25.9-108.1a184.31 184.31 0 00-74-74C596.7 72.8 560 64 520 64h-16c-40 0-76.7 8.8-108.1 25.9a184.31 184.31 0 00-74 74C304.8 195.3 296 232 296 272c0 4.4 3.6 8 8 8z"></path><path d="M940 512H792V412c76.8 0 139-62.2 139-139 0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8a63 63 0 01-63 63H232a63 63 0 01-63-63c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8 0 76.8 62.2 139 139 139v100H84c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h148v96c0 6.5.2 13 .7 19.3C164.1 728.6 116 796.7 116 876c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8 0-44.2 23.9-82.9 59.6-103.7a273 273 0 0022.7 49c24.3 41.5 59 76.2 100.5 100.5S460.5 960 512 960s99.8-13.9 141.3-38.2a281.38 281.38 0 00123.2-149.5A120 120 0 01836 876c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8 0-79.3-48.1-147.4-116.7-176.7.4-6.4.7-12.8.7-19.3v-96h148c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM716 680c0 36.8-9.7 72-27.8 102.9-17.7 30.3-43 55.6-73.3 73.3C584 874.3 548.8 884 512 884s-72-9.7-102.9-27.8c-30.3-17.7-55.6-43-73.3-73.3A202.75 202.75 0 01308 680V412h408v268z"></path></svg>
                <span style="margin-top: -2px;float: right;margin-left: 5px;">{{t('apiPage.debug')}}</span>
            </template>
            <debug-tab ref="debugtabRef" :detail="detail" :currentMethod="currentMethod" />
          </a-tab-pane>
        </a-tabs>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, computed, toRefs, watch, onActivated, ref, nextTick } from 'vue';
import { useStore } from "vuex";
import { GlobalState } from "@/store";
import { useRoute } from "vue-router";
import { copyTextToClipboard } from "@/utils";
import { Tag, Select, message, Tabs, Alert, Button } from "ant-design-vue";
import { cloneDeep } from "lodash";
import { CopyOutlined } from "@ant-design/icons-vue";
import { ApiItem } from "@/api/interface/apiData";
import TableTab from "./tableTab.vue";
import JsonTab from "./jsonTab.vue";
import DebugTab from "./debug";
import * as Types from "@/store/modules/App/types";
import { PageDataItemState } from "@/store/modules/App/interface";
import Skeleton from "./skeleton.vue";
import { useI18n } from "@/hooks/useI18n";

export default defineComponent({
  name: "ApiDetail",
  components: {
    [Tag.name]: Tag,
    ASelect: Select,
    ASelectOption: Select.Option,
    CopyOutlined,
    [Tabs.name]: Tabs,
    [Tabs.TabPane.name]: Tabs.TabPane,
    [Alert.name]: Alert,
    [Button.name]: Button,
    TableTab,
    JsonTab,
    DebugTab,
    Skeleton,
  },
  setup() {
    const { t } = useI18n();
    const route = useRoute();
    let store = useStore<GlobalState>();
    const detail: ApiItem = {
      title: "",
      menu_key: "",
      children: [],
    };
    const methodList: string[] = [];

    const state = reactive({
      pageData: computed(() => store.state.app.pageData),
      apiObject: computed(() => store.state.apidoc.apiObject),
      detail: detail,
      currentKey: "",
      methodList: methodList,
      currentMethod: "",
      loading: false,
      isReload: false,
    });

    const activeKey = ref('table');
    const debugtabRef = ref();
    

    const fetchData = () => {
      state.loading = true;
      const { query } = route;
      const fullPath = route.fullPath;
      const key = query.key as string;
      state.currentKey = fullPath;
      let detail: PageDataItemState = {
        title: "",
        menu_key: "",
        children: [],
      };

      if (state.pageData[fullPath]) {
        detail = cloneDeep(state.pageData[fullPath]);
      } else if (state.apiObject[key]) {
        detail = cloneDeep(state.apiObject[key]);
        store.dispatch(`app/${Types.ADD_PAGE_DATA}`, {
          ...detail,
          key: fullPath,
        });
      }
      if (detail.menu_key) {
        const method = detail.method as string;
        if (method && method.indexOf(",") > -1) {
          state.methodList = method.split(",");
          state.currentMethod = state.methodList[0];
        } else {
          state.currentMethod = detail.method as string;
        }
        state.detail = detail;
        state.loading = false;
      }
      store.dispatch(`app/${Types.SET_APIDETAIL_INIT_STATE}`, false);
    };

    state.loading = true;
    fetchData();

    const onCopyUrl = () => {
      state.detail.url && copyTextToClipboard(state.detail.url);
      message.success(t("common.copySuccess"));
    };

    const onMethodChange = (value: string) => {
      state.currentMethod = value;
    };

    watch(
      () => state.apiObject,
      () => {
        if (!(state.detail && state.detail.menu_key)) {
          fetchData();
        }
      }
    );

    onActivated(() => {
      const { query } = route;
      const fullPath = route.fullPath;
      const key = query.key as string;
      const oldData = JSON.stringify({ ...state.pageData[fullPath], menu_key: "" });
      const newData = JSON.stringify({ ...state.apiObject[key], menu_key: "" });
      if (!(state.pageData[fullPath] && state.apiObject[key] && oldData === newData)) {
        state.isReload = true;
      }
    });

    function onReload() {
      state.loading = true;
      const { query } = route;
      const fullPath = route.fullPath;
      const key = query.key as string;
      const detail = cloneDeep(state.apiObject[key]);
      store.dispatch(`app/${Types.ADD_PAGE_DATA}`, {
        ...detail,
        key: fullPath,
      });
      if (detail.menu_key) {
        const method = detail.method as string;
        if (method && method.indexOf(",") > -1) {
          state.methodList = method.split(",");
          state.currentMethod = state.methodList[0];
        } else {
          state.currentMethod = detail.method as string;
        }
        state.detail = detail;
        state.loading = false;
        state.isReload = false;
      }
    }

    const send = () => {
        activeKey.value = 'debug';
        console.log(debugtabRef.value)
        nextTick(()=>{
            debugtabRef.value.excute();
        })
    };

    return { ...toRefs(state), activeKey, debugtabRef, onCopyUrl, send , onMethodChange, onReload, t };
  },
});
</script>
<style lang="less" scoped>
@import "./index.less";
</style>
